package gas.model;

import gas.view.*;

/***
 * User is the data structure that holds user attributes, functions and properties.
 * 
 * Attributes:
 * username: the users login information.
 * password: encrypted password.
 * email:
 * points:
 * prefs:
 * 
 * @author Alfred Tarng
 *
 */
public class User {

    /**
     * Separate Preferences into their own class perhaps? 
     */
    private String username;
    private String password;
    private String email;
    private String id;
    private int points;
    // private updateHistory?
    private Preferences prefs;
    
  /** Default User Constructor
   */
  public User(){
      prefs = new Preferences();
  }

  public User(String un, String pw, String em){
      this.setUsername(un);
      this.changePassword(pw);
      this.setEmail(em);
      prefs = new Preferences();
    }

  /** User Constructor
   */
  public User(String un, String pw, String em, String id){
      this.setUsername(un);
      this.changePassword(pw);
       this.setEmail(em);
       this.setID(id);
       prefs = new Preferences();
  }
    public Preferences getPrefs() { return prefs; }
    public void setPrefs(Preferences prefs) {this.prefs = prefs;}
    public String getUsername() { return username; }
    public boolean setUsername(String username) {
      if( username.length() > 14 ) return false;
        this.username = username;
        return true;
    }
    public String getPassword() {
        return password;
    }
    public boolean changePassword(String password) {
      
   // TODO: add checks for valid password.
      boolean punctuationCheck = false;
      boolean numberCheck = false;
      boolean capsCheck = false;
      boolean passAll;
      if( password.length() < 6 ){
        System.err.println("Password Length is too Short");
        return false;
      }
      
      // Check for Password
      for ( int i = 0; i < password.length(); i++ ){
        /*
        if ( (password[i] > 32 && password[i] < 48) || //checks for punctuation_0
             (password[i] > 57 && password[i] < 65) || 
             (password[i] > 91)
           )
        */
        punctuationCheck = true;
        
        if( password.charAt(i) >= 48 && password.charAt(i) < 58 ) numberCheck = true;
        if( password.charAt(i) >  64 && password.charAt(i) < 91 ) capsCheck = true;
      }

      if(!punctuationCheck)
        System.err.println("Needs punctuation in Password!");
      if(!numberCheck)
        System.err.println("Needs a number in Password!");
      if(!capsCheck)
        System.err.println("Needs capitalization in Password!");

       passAll = numberCheck & capsCheck;
      
      if (passAll){
        this.password = password;
        return passAll;
      }
          
        return false;
    }
    
    public boolean isAdmin(){
      if ( this instanceof Admin )
        return true;
      return false;
    }
    
    /***
     * Email Enumerator.
     * Just a test in coding style, limiters.
     * 
     * @author cs120fao
     *
     */
                public enum EmailEnum{
                    EDU(0, ".edu"),
                    COM(1, ".com"),
                    NET(2, ".net"),
                    ORG(3, ".org");
                    private int test;
                    private String suffix;
                    EmailEnum( int test, String emailSuffix){
                        this.test = test;
                        this.suffix = emailSuffix;
                    }
                    public String suffix(){ return suffix; }
                }
    
    /*** TODO: Implement Correct Email Syntax checks.
     * This will include checking for the "@" char symbol,
     * as well as valid suffixes ".edu"/".com"/"net" etc.
     * @param email
     * @return
     */
    public boolean setEmail(String email) {
      boolean passAll = true;
      boolean syntaxCheck = false;
      boolean validityCheck = true;
      int atCounter = 0;
      
      /* Verifies email ends in enumerated value... */
      for ( EmailEnum e : EmailEnum.values()){
          if( email.endsWith(e.suffix()) ){
            System.err.println(email + " ends with " + e.suffix);
                                            syntaxCheck = true;
                                            break; }
      } if ( !syntaxCheck ) System.err.println( "Did not pass suffix check" );
      else {
      /* Verifies there is an @ character.... */
      for ( int i = 0; i < email.length(); i++ ){
        if ( email.charAt(i) == '@' ) ++atCounter;
      } syntaxCheck = syntaxCheck & (atCounter == 1);
      if ( !syntaxCheck ) System.err.println( "Did not pass @ check, @counter: " + atCounter );
      }
      
      passAll = (syntaxCheck && validityCheck);
      if ( passAll ) System.err.println( email + " is good." );
      this.email = (passAll) ? email : this.email; //"invalid Email!";
        
      return passAll;
    }
    
    public String getEmail() {
        return email;
    }
    public void setPoints(int points) {
        this.points = points;
    }
    public int getPoints() {
        return points;
    }
    
    public void setID(String id) { this.id = id; }
    public String getId() { return id; }
    
    public String toString(){
      String retString = "\nUser Name:  " + getUsername() +
                         "\nPassword:   " + getPassword() +
                         "\nEmail:      " + getEmail() +
//                         "\nAdmin:      " + isAdmin() +
                         "\nScore:      " + getPoints();
      
      return retString;
    }    
    
    /*** Self Tester ***/
  public static boolean selfTest(){
    boolean passAll = true;
    User testUser = new User();
    
    testUser.setUsername("Bob");
    passAll = passAll & "Bob".equals(testUser.getUsername());
    
    /* testing good email */
    testUser.setEmail("bob@gmail.com");
    passAll = passAll & "bob@gmail.com".equals(testUser.getEmail());
    if(!passAll) System.err.println("Failed: good email did not get set.");
    /* testing bad email_1 */
    passAll &= !(testUser.setEmail("bobgmail.com"));
    if(!passAll) System.err.println("Failed: bad email set.");
    /* testing bad email_2 */
    passAll &= !(testUser.setEmail("bob@gmail"));
    if(!passAll) System.err.println("Failed: bad email set.");
    /* testing bad email_3 */
    passAll &= !(testUser.setEmail("bob@gmail@.edu"));
    if(!passAll) System.err.println("Failed: bad email set.");
    
    testUser.changePassword("Bobs_password1");
    passAll = passAll & "Bob\'s password".equals(testUser.getPassword());
    
    System.out.println(testUser.toString());
    
    
    return passAll;
  }
  public static void main(String[] args){
    selfTest();
  }
    
}
